﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoritmosTA1
{
    class Matriz
    {

        public Matriz()
        {
        }

        public nodo m; //nodo root
        int filaMax;
        int colMax;

        

        public void crear(int filas, int cols)
        {
            //nodo raiz
            m = new nodo(null, 0, 0);
            m.sigfil = m;
            m.sigcol = m;

            //fila 0
            int i = 1;
            nodo q = m;

            while (i <= filas)
            {
                nodo nuevo = new nodo(null, i, 0);
                q.sigfil = nuevo;
                nuevo.sigcol = nuevo;
                q = nuevo;
                i++;
            }
            q.sigfil = m;

            //columna 0
            i = 1;
            q = m;
            while (i <= cols)
            {
                nodo nuevo = new nodo(null, 0, i);
                q.sigcol = nuevo;
                nuevo.sigfil = nuevo;
                q = nuevo;
                i++;
            }
            q.sigcol = m;

            filaMax = filas;
            colMax = cols;
        }

        nodo arriba(int f, int c)
        {
            nodo aux = m.sigcol;
            while (aux.col != c)
            {
                aux = aux.sigcol;
            }
            nodo aux1 = aux.sigfil;
            nodo aux2 = aux1.sigfil;
            while ((aux1.fil < f) && (aux2.fil != 0))
            {
                aux = aux1;
                aux1 = aux1.sigfil;
                aux2 = aux2.sigfil;
            }
            if (aux1.fil < f)
            {
                return aux1;
            }
            else
            {
                return aux;
            }
        }

        nodo izquierda(int f, int c)
        {
            nodo aux = m.sigfil;
            while (aux.fil != f)
            {
                aux = aux.sigfil;
            }
            nodo aux1 = aux.sigcol;
            nodo aux2 = aux1.sigcol;
            while ((aux1.col < c) && (aux2.col != 0))
            {
                aux = aux1;
                aux1 = aux1.sigcol;
                aux2 = aux2.sigcol;
            }
            if (aux1.col < c)
            {
                return aux1;
            }
            else
            {
                return aux;
            }
        }

        public void adicionar(ArbolSintaxis arbol, int f, int c)
        {
            if ((f > filaMax) || (c > colMax)){
                Console.WriteLine("La posicion no existe");
            }
            else{
                nodo q=arriba(f,c);
                nodo p = izquierda(f, c);

                //verificar si existe
                nodo aux1 = q.sigfil;
                nodo aux2 = p.sigcol;
                if ((aux1.fil == aux2.fil) && (aux1.col == aux2.col))
                {
                    aux1.info = arbol;
                }
                else
                {
                    //crear nuevo nodo
                    nodo nuevo = new nodo(arbol, f, c);
                    nuevo.sigfil = q.sigfil;
                    q.sigfil = nuevo;
                    nuevo.sigcol = p.sigcol;
                    p.sigcol = nuevo;
                }


            }
        
        }

        public void imprimir(nodo M){
            nodo o;
            int numFilAnt=0,antAux=0,numColAnt=0;
            nodo e;
            nodo aux=M.sigcol;
            Console.Write("  ");
            while(aux.col!=M.col){
                Console.Write(Constantes.Abecedario[aux.col -1] + " ");
                aux=aux.sigcol;
            }
            Console.WriteLine();
            aux=M.sigfil;
        
            while(aux.fil!=M.fil){
                Console.Write(aux.fil + " ");
                o=aux;
                e=aux.sigcol;

                while(o!=e){
                    int numCol=e.col;
                    numColAnt=numCol;
                    int numFil=e.fil;
                    if(numFil==numFilAnt){
                        //calculo de espacios en blanco entre nodos de la misma fila
                        numCol=numCol-antAux;
                    }
                    for(int i=1;i<numCol;i++){
                        Console.Write("  ");
                    }
                    Console.Write(e.info.Info+" ");
                    e=e.sigcol;
                    numFilAnt=numFil;
                    antAux=numColAnt;
                }
                Console.WriteLine(" ");
                aux=aux.sigfil;
            }
        }

        //ingresar solo parametros del tipo A1, A2 ... Z30
        //retorna null si la celda no tiene valor
        public ArbolSintaxis buscarCelda(String celda)
        {

            int col=0;
            int fil=0;
            
            if (celda.Length > 3) return null;

            char letraCol = celda[0];
            for (int i = 0; i < Constantes.Abecedario.Length; i++ )
            {
                if (Constantes.Abecedario[i] == letraCol)
                {
                    col = i + 1;
                    break;
                }
            }

            try{
            fil = Convert.ToInt32(celda.Substring(1,celda.Length - 1));
            }
            catch (Exception e){
                return null;
            }

            if ((col == 0) || (fil == 0)) return null;
            else
            {
                nodo q=arriba(fil,col);
                nodo p = izquierda(fil, col);

                //verificar si existe
                nodo aux1 = q.sigfil;
                nodo aux2 = p.sigcol;
                if ((aux1.fil == aux2.fil) && (aux1.col == aux2.col))
                {
                    return aux1.info;
                }
                else return null;
                
            }

            
        }

        public ArbolSintaxis buscarCeldaPorColFil(int fil, int col)
        {
            if ((col == 0) || (fil == 0)) return null;
            else
            {
                nodo q = arriba(fil, col);
                nodo p = izquierda(fil, col);

                //verificar si existe
                nodo aux1 = q.sigfil;
                nodo aux2 = p.sigcol;
                if ((aux1.fil == aux2.fil) && (aux1.col == aux2.col))
                {
                    return aux1.info;
                }
                else return null;

            }


        }



    }
}
